Three dimensional (3D) graphics processing systems are used to generate images representing views of a 3D scene, e.g. for use in a computer game or other application running on a computer. Modern 3D rendering techniques allow fragments from multiple primitives to be combined in a number of different manners. The type of combining is typically dictated by the type of fragment, which can for example be opaque, translucent or punch through. As a matter of terminology, a “fragment” is an element of a primitive at a sample position. In some examples, a single sample position may correspond to a pixel position of the final rendered image, but in other examples, more than one (e.g. four) sample positions may correspond to each pixel position. A depth buffer can be used to store depth values for an array of sample positions to indicate the current depth at each sample position. A depth test can be performed for incoming fragments with reference to the depth buffer to determine if the fragments are hidden by previously processed fragments. If the incoming fragments are not hidden then the appropriate depth values in the depth buffer can be updated to reflect the depth of the incoming fragments. Opaque fragments are combined by overwriting any previously written fragments. Translucent fragments are processed such that a new translucent fragment value is combined with a previous fragment value using a blending equation that is indicated by the application.
Typically the blending equation uses an alpha value that is sourced from a texture in order to determine how transparent the fragment is. Punch through fragments are processed by performing a test that indicates whether a fragment is “present” i.e. is part of the primitive, or not. If a fragment is determined to not be present then no combining is performed with previously written fragments and, in addition, no depth is written to the depth buffer for that fragment. Typically the punch through test is performed against an alpha value that is sourced from a texture. Punch through/alpha testing may be combined with opaque or translucency blending to produce opaque punch through and translucent punch through fragment types. In the case of punch through and translucency it should be noted that as each case effectively combines a new fragment value with a previous value it is important that the order in which primitives are submitted is preserved.
For purposes of clarity the above types of processing will be referred to as “object types” of opaque, translucent, opaque punch through and translucent punch through. The translucent, and both punch through object types may be referred to herein as “non-opaque object types”. As can be appreciated, the processing of primitives with non-opaque object types is generally more complex than the processing of primitives with an opaque object type.
Some 3D graphics processing systems are tile based rendering systems. These systems have a rendering space which is divided into a plurality of rectangular blocks or tiles. The way in which rendering is performed in these systems is described with reference to a tile based deferred rendering system shown schematically in FIG. 8. This shows a geometry processing unit 802, which receives the image data from an application and transforms it into screen space using well-known methods. The data is then supplied to a tiling unit 804, which inserts the screen space geometry into object lists for a set of defined rectangular regions, or tiles, 806. Each list contains primitives that exist wholly or partially in a sub-region of a screen (i.e. a tile). A list exists for every tile on the screen, although it should be borne in mind that some lists may have no data in them.
The tile lists are then passed tile by tile to a hidden surface removal unit 808 (HSR) and from there to a texturing and shading unit 810 (TSU). The HSR unit 808 performs depth tests on fragments of the primitives in the tile (with reference to a depth buffer as mentioned above) and passes to the TSU 810 only data about fragments which pass the depth test.
An image typically comprises a mixture of opaque, translucent and punch through primitive object types. In order to correctly render such an image, the HSR unit 808 must pass “layers” of fragments which need to be processed to the TSU 810. This is because more than one fragment can contribute to the image data to be applied to a particular sample position. For example the view from the inside of a building looking through a pane of dirty glass requires both the geometry visible through the glass, and then the pane of glass itself to be passed to the TSU 810. This process is referred to as “pass spawning”.
Tags are identifiers which associate a fragment with the primitive of which it is a part, and which allow attributes such as texturing and shading data for the primitive to be fetched when required. Typically, a tile based deferred rendering device of the type shown in FIG. 8 will use a tag buffer at the interface between HSR unit 808 and TSU 810, to hold tags for fragments from the front most primitives (i.e. those which pass the depth test) for each sample position in the tile currently being processed. Tags for opaque fragments which pass the depth tests are typically written into such a tag buffer even if they overwrite an existing tag as that corresponds to the correct operation to combine opaque fragments, as described above. Fragments from translucent and punch through primitives may need to be combined with fragments that they overdraw. The combining of these fragments must be performed in the order that they were submitted by the application.
As such, the HSR unit 808 must flush currently visible tags to the TSU 810 whenever translucent or punch through fragments are found to lie in front of fragments currently stored within the tag buffer, i.e. a pass must be spawned. This results in all currently visible tags stored in the tag buffer being flushed to the TSU 810. In the case of punch through fragments, the validity of fragments, and hence whether their depth values should be updated in the depth buffer, can only be determined by the TSU 810. Therefore, tags for punch through primitives must also be flushed directly after any tags currently stored within the tag buffer have been flushed. It is noted that the combination of a tag and a position in the tag buffer defines a fragment, so the flushing of tags from the tag buffer can be considered to be flushing fragments from the tag buffer. Conceptually, it makes sense to consider fragments being stored in the tag buffer and fragments being flushed out to the texturing and shading unit. In a practical implementation, this conceptual flow of fragments is embodied by storing tags in the tag buffer and flushing tags from the tag buffer.
The graphics data that applications feed into graphics processing systems gets more complex as the user demands and expectations on the applications increase. In particular, the complexity of texturing and shading is increasing, and the use of non-opaque object types is getting more prevalent. This may be problematic since, as described above, the processing of primitives with non-opaque object types is more complicated than the processing of primitives with opaque object types.